﻿using Ops.Host.Core.Entity;

namespace Ops.Host.Core.Services;

internal sealed class NoticeService : ScadaDomainService, INoticeService
{
    private readonly SqlSugarRepository<PtMarkingData> _markingRepo;
    private readonly ILogger _logger;

    private static readonly Dictionary<string, int> _map = new();

    public NoticeService(SqlSugarRepository<PtMarkingData> markingRepo, ILogger<NoticeService> logger)
    {
        _markingRepo = markingRepo;
        _logger = logger;
    }

    public async Task HandleAsync(ForwardData data)
    {
        var name = data.Name ?? "_";
        int count = data.Self().GetInt();

        // 目前产线逻辑是先加数，后打码
        // 和本地数据进行比较
        if (_map.TryGetValue(name, out var count0))
        {
            // 数据没有跳变不处理
            if (count0 == count)
            {
                return;
            }
        }

        // 没有产量的数据不处理
        if (count <= 0)
        {
            return;
        }

        try
        {
            // 获取最近的一条打标数据
            var marking = await _markingRepo.AsQueryable().OrderByDescending(s => s.MarkingTime).FirstAsync();

            // 检测数据是否有绑定（指定车型存在且没有设定产量信息）
            if (marking == null || marking.SN[..1] != name || marking.ProductionCountPerDay > 0)
            {
                return;
            }

            marking.ProductionCountPerDay= count;
            marking.UpdatedTime = DateTime.Now;
            await _markingRepo.AsUpdateable(marking).UpdateColumns(s => new { s.ProductionCountPerDay, s.UpdatedTime }).ExecuteCommandAsync();

            // 成功处理后添加
            MapTrySet(name, count);

            _logger.LogInformation("Tag: {Tag}, SN: {SN}, 车型：{Name}, 产量：{Count}",data.Tag, marking.SN, name, count);

            // 推送消息
            await MessageTaskQueueManager.Default.QueueAsync(new Message(data.Schema.Line, data.Schema.Station, MessageClassify.Outbound, "", marking));
        }
        catch (Exception ex)
        {
            MapTrySet(name, 0); // 置为 0，防止因为短暂的异常导致数据不能写入

            _logger.LogError(ex, "产量记录出现异常，Tag: {Tag}, 车型：{Name}", data.Tag, name);
        }
    }

    private static void MapTrySet(string name, int count)
    {
        if (!_map.ContainsKey(name))
        {
            _map.TryAdd(name, count);
        }
        else
        {
            _map[name] = count;
        }
    }
}
